"use strict";

const ValidationService = require("../services/ValidationService.js");
const FileService = require("../services/FileService.js");

/**
 * generate folders and subfolders.
 * @class DirectoryGenerator
 * @example 
 * let generator = new DirectoryGenerator();
 */
/*export*/ class DirectoryGenerator {
  /**
   * constructor
   */
  constructor() {
    this.validationService = new ValidationService();
    this.fileService = new FileService();
    this._register();
  }

  /**
   * register rules
   * @access private
   */
  _register() {
    const rules = {
      name: {
        name: "name",
        required: "custom:name|structure",
        type: "string"
      },
      parent: {
        name: "parent",
        required: false,
        type: "string"
      },
      structure: {
        name: "structure",
        required: "custom:name|structure",
        type: "string"
      },
      custom: {
        "name|structure": function(payload) {
          return true === payload && ("name" in payload ||
                                      "structure" in payload);
        }
      }
    };
    this.validationService.register(rules);
  }

  /**
   * create a folder
   * @param {Object} payload
   * @param {string} payload.name directory to create
   * @param {string} payload.structure list of directories to create
   * @param {string} payload.parent directory to create into
   * @returns {Object} status
   */
  findOrCreate(payload) {
    this.validationService.execute(payload);
    if (500 === this.validationService.status.code) {
      return this.validationService.status;
    }
    if ("name" in payload) {
      return this.fileService.findOrCreate(payload)
        .then(function(result) {
          if (true === result) {
            this.validationService.status.message = `${payload.name} already exists, nothing to do`;
            return this.validationService.status;
          }
          this.validationService.status.message = `${payload.name} created`;
          return this.validationService.status;
        });
    }
    if(!("structure") in payload ||
       !(Array.isArray(payload.structure))) {
      return new Promise(_,reject => reject(false));
    }
    return Promise.all(
      payload.structure
        .map((path) => this.fileService.findOrCreate({name: path}))
    )
      .then(() => this.validationService.status);
  }
}
module.exports = DirectoryGenerator;
